package lumis.service.doui.propertybag;

import java.util.List;
import java.util.Map;

import org.w3c.dom.Node;

import lumis.doui.source.IDataProvider;
import lumis.doui.source.ISourceData;
import lumis.doui.source.TabularData;
import lumis.doui.table.TableSource;
import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.channel.ChannelConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.propertybag.PropertyBag;
import lumis.util.ITransaction;
import lumis.util.XmlUtil;

/**
 * Provides the inherited properties of a property bag.
 * <p>
 * Fills the fields name (string) and values (html).
 * <p>
 * Must contains the elements:
 * <ul>
 * 	<li><code>propertyBagSourceId</code>: The identifier of the source that contains the propertyBagId value.</li>
 * 	<li><code>propertyBagFieldId</code>: The identifier of the field (in the source specified above) that contains the propertyBagId value.</li>
 * </ul>
 * 
 * @version $Revision: 10825 $ $Date: 2009-08-04 12:36:40 -0300 (Tue, 04 Aug 2009) $
 * @since 5.0.0
 */
public class InheritedPropertiesDataProvider implements IDataProvider<TableSource>
{
	public void loadData(SessionConfig sessionConfig, TableSource source, ITransaction transaction) throws PortalException 
	{
		PropertyBag parentPropertyBag = getParentPropertyBag(sessionConfig, source, transaction);
		if(parentPropertyBag != null)
		{
			TabularData data = source.getData();
			Map<String, List<String>> valueMap = parentPropertyBag.getValueMap();
			for (Map.Entry<String, List<String>> entry: valueMap.entrySet())
			{
				String propertyName = entry.getKey();
				
				if(parentPropertyBag.getProperty(propertyName).isPrivate())
					continue;
				
				ISourceData newRow = data.addRow();
				newRow.put("name", propertyName);
				StringBuffer stringValues = new StringBuffer();
				List<String> propertyValues = entry.getValue();
				for(String value:propertyValues)
				{
					stringValues.append(XmlUtil.encodeXml(value));
					stringValues.append("<br/>");
				}
				newRow.put("values", stringValues.toString());
			}
			data.sort(source);
		}
	}

	/**
	 * Returns the parent property bag for an item being added or edited.
	 * @param sessionConfig user session information.
	 * @param source the source of the item being added or edited.
	 * @param transaction the transaction for persistence access.
	 * @return the parent property bag, or <code>null</code> if it does not exist.
	 * @since 5.0.0
	 */
	private PropertyBag getParentPropertyBag(SessionConfig sessionConfig, TableSource source, ITransaction transaction) throws PortalException
	{
		Node sourceNode = source.getDefinitionNode();
		String propertyBagSourceId = XmlUtil.readNodeString("propertyBagSourceId", sourceNode);
		String propertyBagFieldId = XmlUtil.readNodeString("propertyBagFieldId", sourceNode);
		TableSource propertyBagSource = (TableSource)source.getSourceContainer().getSourceById(propertyBagSourceId);
		
		// try to get propertyBag from mapped source.
		String pkValue = (String)propertyBagSource.getParameterValue(propertyBagSource.getPrimaryKeyField().getId());
		String propertyBagId = null;
		PropertyBag parentPropertyBag = null;
		if(pkValue != null)
		{
			propertyBagId = propertyBagSource.readData(pkValue, transaction).get(propertyBagFieldId, String.class);
			PropertyBag propertyBag = ManagerFactory.getPropertyBagManager().get(propertyBagId);
			parentPropertyBag = propertyBag.getParentPropertyBag();
		}
		else
		{
			// try to get propertyBag from parent channelId
			String parentChannelId = source.getDouiContext().getRequest().getParameter("parentChannelId");
			if(parentChannelId != null)
			{
				ChannelConfig channelConfig = ManagerFactory.getChannelManager().get(sessionConfig, parentChannelId, transaction);
				propertyBagId = channelConfig.getPropertyBagId();
				parentPropertyBag = ManagerFactory.getPropertyBagManager().get(propertyBagId);
			}
		}
		
		return parentPropertyBag;
	}
}
